using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Collections.ObjectModel;
using System.IO;
using System.Xml.Serialization;
using System.IO.IsolatedStorage;
using System.Reflection;

namespace SharePointSearchBench
{
    /// <summary>
    /// An all-purpose collection class used for saving simple lists of text 
    /// values to disk.
    /// </summary>
    public class SavedStringCollection : ObservableCollection<string>
    {
        private string saveFileName;
        private int maxItems = 100;

        /// <summary>
        /// Creates a new instance of the class.
        /// </summary>
        public SavedStringCollection():base()
        {
        }

        /// <summary>
        /// Gets or sets the name of the file used for saving the data.
        /// </summary>
        public string SaveFileName
        {
            get { return this.saveFileName; }
            set { this.saveFileName = value; }
        }

        /// <summary>
        /// Gets or sets the maximum number of items that can be saved in the collection.
        /// </summary>
        public int MaxItems
        {
            get { return this.maxItems; }
            set { this.maxItems = value; }
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnCollectionChanged(e);

            if(this.Count > this.MaxItems)
            {
                this.RemoveAt(this.Count - 1);
            }

        }

        void Clean()
        {
            for(int i = this.Count - 1;i >= 0;i--)
            {
                if(string.IsNullOrEmpty(this[i]))
                {
                    this.RemoveAt(i);
                }
            }
        }

        /// <summary>
        /// Obtains the persisted list of strings from disk.
        /// </summary>
        public void Load()
        {
            if(this.SaveFileName.Length == 0)
            {
                throw new SharePointSearchBenchException("The SaveFileName property must be set before loading.");
            }

            IsolatedStorageFileStream stream = null;
            IsolatedStorageFile file = null;
            try
            {
                file = IsolatedStorageFile.GetUserStoreForAssembly();

                string[] files = file.GetFileNames(this.SaveFileName);
                if(files.Length > 0)
                {
                    stream = new IsolatedStorageFileStream(this.SaveFileName, FileMode.Open, FileAccess.Read, file);

                    XmlSerializer serializer = new XmlSerializer(typeof(SavedStringCollection));
                    SavedStringCollection items = serializer.Deserialize(stream) as SavedStringCollection;

                    foreach(string item in items)
                    {
                        base.Add(item);
                    }
                }
            }
            finally
            {
                if(file != null)
                {
                    file.Dispose();
                }

                if(stream != null)
                {
                    stream.Dispose();
                }
            }

        }

        /// <summary>
        /// Persists the collection of strings to disk.
        /// </summary>
        public void Save()
        {
            using(IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForAssembly())
            {
                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(this.SaveFileName, FileMode.Create, FileAccess.Write, file))
                {
                    this.Clean();
                    XmlSerializer serializer = new XmlSerializer(typeof(SavedStringCollection));
                    serializer.Serialize(stream, this);
                }
            }
        }

    }
}
